﻿// Implements functionality for a container that contains a single item
define([
    'Wjs/ui/elements/mixins/Container',
    'Wjs/ui/elements/mixins/Loadable'
],
function () {
    'use strict';

    return Wjs.defineOnce({

        type: 'SingleContainer',

        internal: {

            base: Wjs.getType('Container'),

            mixins: [
                Wjs.getType('Loadable')
            ],

            listeners: {

                onDomElementCreated: function () {

                    if (this.item) {

                        this.item.render();

                        // Fire the item rendered event
                        if (this.itemsRenderedHandler) {

                            this.itemsRenderedHandler();
                        }
                    }

                },

                // Called before the element is destroyed
                onDestroy: function () {

                    this.clearItem();
                }
            }

        },

        setHtml: function (content) {
            var item = this.getItem();

            if (item && item instanceof Wjs.getType('Html')) {

                if (content != item.getHtml()) { // The content is different

                    item.setHtml(content);
                }

            }
            else { // Different type

                this.setItem({}, 'Html');

                this.getItem().setHtml(content);
            }

            return this;
        },

        getHtml: function () {
            var item = this.getItem();

            if (item) {

                return item.getHtml();
            }

            return null;
        },

        setText: function (content) {
            var item = this.getItem();

            if (item && item instanceof Wjs.getType('Text')) {

                if (content != item.getText()) { // The content is different

                    item.setText(content);
                }

            }
            else { // Different type

                this.setItem({}, 'Text');

                this.getItem().setText(content);
            }

            return this;
        },

        getText: function () {
            var item = this.getItem();

            if (item) {

                return item.getText();
            }

            return null;
        },

        setItem: function (item, altType) {

            if (this.getItem()) { // Clear any existing item first since only one is expected

                this.clearItem();
            }

            item = this.createItem(item, altType);

            item.setParent(this);

            this.item = item;

            this.handleItemAdded(item);

            return this;
        },

        getItem: function () {

            return this.item;
        },

        // Recursively returns all the children of this view that match the criteria of the test function
        down: function (test, output) {
            var item = this.getItem(),
                done = false;

            if (!output) { // Assume parent will not provide the output array

                output = [];
                done = true;
            }

            if (item) { // Maybe the item was not set

                if (!test || test(item)) {

                    output.push(item);
                }

                if (item.down) { // Recurse

                    item.down(test, output);
                }
            }

            if (done) {

                return output;
            }
        },

        // Removes the single item of this container, it does not destroy it
        removeItem: function() {
            var item = this.item;

            item.setParent(null);

            this.item = null;

            return item;
        },

        // Destroys the item in the container
        clearItem: function () {

            if (!this.item) {

                return; // Nothing to destroy
            }

            this.item.destroy();

            delete this.item;

            if (this.itemsClearedHandler) {

                this.itemsClearedHandler();
            }
        },

        beforeLoadHandler: function () {

            this.clearItem();
        },

        loadHandler: function (data, contentType) {

            switch (contentType) {

                case 'html':
                    {
                        this.setHtml(data);
                    }
                    break;

                case 'json':
                    {
                        this.record = data; // Keep the data as a record

                        if (this.template) {

                            this.setHtml(this.template(data));
                        }
                        else if (this.draw) {

                            this.setHtml(this.draw(data));
                        }
                        else {

                            this.setText(JSON.stringify(data));
                        }
                    }
                    break;

                default: // 'text'
                    {
                        this.setText(data);
                    }
                    break;
            }

            this.getItem().record = data;
        },

        getContent: function () {

            return this.getItem().getContent();
        },

        getRecord: function () {

            return this.record;
        }

    });

});